#pragma once

#include <cstdlib>
#include <cmath>

// evaluate a specific board position statically (quick and poor)
int quick_static_eval(I_CHESS_POSITION *p)
{
	// if the material values are the same, no more calculations
	if (p->mat[I_SIDE_WHITE] == p->mat[I_SIDE_BLACK]) return 0;
	
	// current player
	int const c = p->col;
	
	int op = 1 ^ c, df, np, sn;
	int mt = p->mat[I_SIDE_WHITE] + p->mat[I_SIDE_BLACK];
	
	if (p->mat[c] > p->mat[op])
	{
		// this player is winning
		df = p->mat[c] - p->mat[op];
		np = p->pwn[c]; sn = 1;
	}
	else
	{
		// other player is winning
		df = p->mat[op] - p->mat[c];
		np = p->pwn[op]; sn = -1;
	}
	
	// a stolen evaluation formula, to be rewritten and improved later
	return sn * (std::min(2400, df) + (df * (12000 - mt) * np) / (6400 * (1 + np)));
};

// the factor for castling is equivalent to the value of a single knight
int const I_MSE_CASTLING_FACTOR = GAME.PIECE_VALUE[I_PIECE_KN];

// evaluate a specific board position statically
int main_static_eval(I_CHESS_POSITION *p)
{
	// constants and variables
	int const c = p->col, op = 1 ^ c;
	int ccount = 2, eval = 0;
	
	// 1. material value bonus
	eval += p->mat[c] - p->mat[op];
	
	// 2. position value bonus
	eval += p->pos[c];
	
	// how many castling options are available?
	ccount -= ((p->cst >> (I_CASTLE_KI + c)) & 1);
	ccount -= ((p->cst >> (I_CASTLE_QU + c)) & 1);
	
	// give a bonus if we can castle both directions
	if (ccount == 2) ++ccount;
	
	// 3. castling bonus
	eval += I_MSE_CASTLING_FACTOR * ccount;
	
	return eval;
};

// evaluate a specific board position via genetic algorithm
int genetic_static_eval(I_CHESS_POSITION *p)
{
	return 0;
};
